package WebSocket.component;

import lombok.SneakyThrows;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author caihe
 * @date 2022/10/17 21:22
 */
@ServerEndpoint("/single/websocket/{userCode}")
@Component
public class SingleWebSocketServer {
    private static final Logger log = LoggerFactory.getLogger(SingleWebSocketServer.class);
    /**
     * 用来存放每个客户端对应的 WebSocketServer 对象
     */
    private static final ConcurrentHashMap<Long, Session> WEB_SOCKET_MAP = new ConcurrentHashMap<>();
    
    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("userCode") Long userCode) {
        session.setMaxIdleTimeout(600000);
        /**
         * 与某个客户端的连接会话，需要通过它来给客户端发送数据
         */

        WEB_SOCKET_MAP.put(userCode, session);
        
        log.info("用户:" + userCode + "连接成功");
        try {
            sendMessage(session, "连接成功！");
        } catch (IOException e) {
            log.error("用户:" + userCode + ",网络异常!!!!!!");
        }
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(@PathParam("userCode") Long userCode) {
        WEB_SOCKET_MAP.remove(userCode);
        log.info("用户:" + userCode + "退出");
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(@PathParam("userCode") Long userCode, String message) {
        log.info("用户【{}】收到消息【{}】", userCode, message);
    }

    /**
     * 实现服务器主动推送
     */
    public void sendMessage(Session session, String message) throws IOException {
        session.getBasicRemote().sendText(message);
    }
    
    
    @SneakyThrows
    public void sendMessage(Long userCode, String message) {
        Session session = WEB_SOCKET_MAP.get(userCode);
        sendMessage(session, message);
    }
}
